home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOpus Plus
/
DOpus Plus.iso
/
Tutorial
/
C Guide
/
Simple_Module2
/
IPCWindow
/
IPCWindow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-01
|
12KB
|
306 lines
/*******************************************************************
IPCWindow.c
Does open a simple window with some easy gadgets, does create a
new process, is protected to launch not twice and does show all
arguments even if they are given with a new command.
*********************************************************************/
#define PARENT
#include "/includes/Window.h"
typedef struct _PassingData
{
ULONG a4; // to store a4 (module is a4 relative)
struct Library *library; // to store a pointer to dopus5.library
struct Library *module; // to store a pointer to this module
IPCData *ipc; // to store our NEW handle
struct Screen *screen;
} PassingData;
/********************************************************************/
// locale prototypes and variables
ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
register __a1 PassingData *pd );
void __saveds New_Proc( void );
BOOL OpenDOpusWin( WindowHandle *wh ); // the same old function
BOOL HandleWindow( WindowHandle *wh ); // the same old function
extern IPCData *proc_ipc;
// declared in modinit.c, because must be initialized to NULL on startup
/********************************************************************/
// this is the same function like in DetachWindow.
// it is the first special function we need...
void OwnWindow( STRPTR args, struct Screen *screen )
{
PassingData *pd;
if( (pd = AllocMemH(mempool, sizeof(PassingData))) ) // allocate some memory
{
pd->screen = screen; // store the screen pointer
if( !proc_ipc ) // only if the process is not already running
{
// now some special stuff, but everything is needed here...
pd->a4 = getreg( REG_A4 );
pd->module = (struct Library *) getreg( REG_A6 );
pd->library = DOpusBase;
// now we are ready to call IPC_Launch()
IPC_Launch( 0,
&proc_ipc, // pointer to pointer to the IPC of the new process, for storing...
"ExampleWindow", // name of the new process
(ULONG) New_Proc, // entrypoint of the new process
4096, // stack to use
(ULONG) pd, // data to pass to the new process
DOSBase ); // pointer to dos.library
if( !proc_ipc ) // if detaching failed...
{
FreeMemH( pd );
return;
}
Delay( 10 ); // give a small time for startup...
// not really needed
}
// now should our process running
// since we use in the process not the arguments on startup to save
// some work, we have to pass it now.
IPC_Command( proc_ipc, // "address" (IPCData) of receiver
NULL, // we use no commands here
NULL, // also no flags
args, // our data to pass to the new process
NULL, // no other data (will be FreeVec'd)
REPLY_NO_PORT ); // use normal DOpus IPC_Reply() later
FreeMemH( pd );
}
// ready... :)
}
// let's do now the second special function
ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
register __a1 PassingData *pd )
{
// you may use this function also to setup things for your
// main process, but you should not call any IPC functions here !
// we do only the minimum required..., but you will get some small
// warnings from your compiler. Just ignore them now - they does
// not appear, if we would do here some more things...
struct Library *DOpusBase;
// fix A4
putreg( REG_A4, pd->a4 );
// store IPC pointer
pd->ipc = ipc;
// get dopus.library - one warning now
DOpusBase = pd->library;
// now may follow your initialization
// if something fails and you must quit, you should do:
// return FALSE;
// increase our library counter, so we can not be flushed
// do not forget to decrease it, if your detached process ends
pd->module->lib_OpenCnt++;
return TRUE; // all was successfully
}
void __saveds New_Proc( void )
{
// this is now just the same like until now our OwnWindow() function
WindowHandle *wh;
PassingData *pd;
IPCData *ipc;
IPCMessage *ipcmsg;
struct Library *DOpusBase;
struct Library *module;
// but we must do some additional things
// get dopus library
if( !(DOpusBase = (struct Library *) FindName(&((struct ExecBase *)*((ULONG *)4))->LibList, "dopus5.library")) )
return;
// do startup
ipc = IPC_ProcStartup( (ULONG *) &pd, New_Proc_Startup );
// fix A4 so we can access global data in the module (eg library bases)
putreg( REG_A4, pd->a4 );
// we must store this pointer too
module = pd->module;
// something failed until now ?
if( !ipc )
{
if( pd )
{
IPC_Free( pd->ipc ); // possible it has a value here
FreeMemH( pd ); // free our memory
}
return;
}
if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
{
if( OpenDOpusWin(wh) ) // open the window
{
// before we have set on this place the value of our
// textgadget, but now we have not the arguments. So
// we wait to set the value until the command arrives.
while( TRUE )
{
// I use here Wait(), so it is easier with the changes
wh->signals = Wait( 1 << proc_ipc->command_port->mp_SigBit | // wait for IPC messages
1 << wh->win->UserPort->mp_SigBit ); // wait for window events
if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
if( HandleWindow(wh) )
break; // does end the while loop
if( wh->signals & 1 << proc_ipc->command_port->mp_SigBit ) // if we have got an IPC message
{
while( (ipcmsg = (IPCMessage *) GetMsg(proc_ipc->command_port)) )
{
// we copy now the arguments into the text gadget
// if we have supplied some..., else it will be cleared
// I do not cut here the last signs...
SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) ipcmsg->data );
IPC_Reply( ipcmsg ); // do not use ReplyMsg() or something else !
}
}
}
CloseConfigWindow( wh->win );
}
FreeMemH( wh ); // free our memory
}
// decrease our Library access counter, since we have increased it before
--module->lib_OpenCnt;
// since we are here a detached process, we must do some other cleanup too
IPC_Free( proc_ipc );
proc_ipc = NULL; // do not forget this...
}
/********************************************************************/
// This function does open our window. We could have done this in the
// function OwnWindow() too, but we need this function later again.
BOOL OpenDOpusWin( WindowHandle *wh )
{
NewConfigWindow ncfgwin; // we need a NewConfigWindow structure too
// of couse you could also allocate it with
// AllocMemH()...
// and have to fill it
ncfgwin.nw_Parent = wh->screen; // open on this screen
// getting a localized title...
ncfgwin.nw_Title = DOpusGetString( locale, MSG_WINDOW_TITLE );
ncfgwin.nw_Dims = &cfgwin; // a pointer to the ConfigWin structure
ncfgwin.nw_Locale = locale; // the module locale pointer (from modinit.c)
ncfgwin.nw_Port = NULL; // we doesn't supply a port
ncfgwin.nw_Font = NULL; // just taking the screen font
ncfgwin.nw_Flags = WINDOW_REQ_FILL | // fill with stripple pattern
WINDOW_AUTO_KEYS | // handle keys automatic
WINDOW_SCREEN_PARENT; // nw_Parent points to a screen
if( (wh->win = OpenConfigWindow(&ncfgwin)) ) // open the window
{
if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
return TRUE;
CloseConfigWindow( wh->win ); // in error case do not forget :-)
}
return FALSE;
}
/********************************************************************/
// we does only close the window, if the closegadget was pressed
// if you want to close it within a gadget, you must only in the
// right case set "stop" to TRUE
BOOL HandleWindow( WindowHandle *wh )
{
BOOL stop = FALSE;
ULONG value;
while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
{
switch( wh->imsg->Class ) // let's handle the IDCMP
{
case IDCMP_GADGETUP:
switch( GET_ID(wh->imsg) )
{
case GADGET_ID_CYCLE: // we copy simply the same text to the text gadget
value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE ) + MSG_CLICK_ME;
SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, value) );
break;
case GADGET_ID_OKAY: // doing a message
SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
break;
case GADGET_ID_CANCEL:
SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
break;
}
break;
case IDCMP_CLOSEWINDOW:
// we can not simply return here, the IntuiMessage must replied first
stop = TRUE;
break;
}
ReplyWindowMsg( wh->imsg );
// remember: You should not use any other routines
// to get/reply the messages of this window than
// GetWindowMsg() and ReplyWindowMsg() !!
}
return stop;
}